

package cn.shengchao.examstar.product.acl.adapters.repositories;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.shengchao.examstar.product.acl.ports.repositories.ICourseRepository;
import cn.shengchao.examstar.product.acl.ports.repositories.message.MemberCourseOrder;
import cn.shengchao.examstar.product.domain.entity.*;
import cn.shengchao.examstar.product.domain.valobj.Price;
import cn.shengchao.examstar.product.domain.valobj.ProductName;
import cn.shengchao.examstar.product.infrastructure.dao.*;
import cn.shengchao.examstar.product.infrastructure.dao.po.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import top.continew.starter.extension.crud.model.entity.BaseIdDO;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Repository
public class CourseRepository implements ICourseRepository {

    @Autowired
    private ProductCourseDao productCourseDao;

    @Autowired
    private ProductCourseNodesDao productCourseNodesDao;

    @Autowired
    private ProductCourseBuySumDiscountConfigDao courseBuySumDiscountConfigDao;

    @Autowired
    private ProductCourseNodesFreeUnlockDao productCourseNodesFreeUnlockDao;

    @Autowired
    private TProductSpecificationTypeDao tProductSpecificationTypeDao;

    @Override
    public Long edit(Course course) {
        Integer courseType = 0;
        TProductCourse existingCourse = null;
        if (course.getId()!=null){
            existingCourse = productCourseDao.selectById(course.getId());
            if (existingCourse != null) {
                courseType=(existingCourse.getCourseType()==null?0:existingCourse.getCourseType());
            }
        }
        TProductCourse tProductCourse = new TProductCourse();
        tProductCourse.setCardUrl(course.getCardUrl());
        tProductCourse.setId(course.getId());
        tProductCourse.setKnowledgeNodeNum(course.getKnowledgeNodeNum());
        tProductCourse.setName(course.getName().getValue());
        tProductCourse.setPrice(course.getPrice().getPrice());
        tProductCourse.setDiscountPrice(course.getDiscountPrice().getPrice());
        tProductCourse.setDetails(course.getDetails());
        tProductCourse.setDescription(course.getDescription());
        tProductCourse.setScore(course.getScore());
        tProductCourse.setImageUrl(course.getImageUrl());
        tProductCourse.setSort(course.getSort());
        tProductCourse.setStatus(course.getStatus());
        tProductCourse.setCourseType(courseType);
        tProductCourse.setVirtualPurchaseNum(course.getVirtualPurchaseNum());
        tProductCourse.setActualPurchaseNum(course.getActualPurchaseNum());
        tProductCourse.setIsVirtual(course.getIsVirtual());
        tProductCourse.setIsLogistics(course.getIsLogistics());
        tProductCourse.setDeleted(0L);
        tProductCourse.setClassHour(course.getClassHour());
        productCourseDao.insertOrUpdate(tProductCourse);
        if (course.getSpecificationType() != null) {
            tProductSpecificationTypeDao.delete(new LambdaQueryWrapper<TProductSpecificationType>()
                    .eq(TProductSpecificationType::getProductId, tProductCourse.getId()));
            for (String specificationType : course.getSpecificationType()) {
                TProductSpecificationType tProductSpecificationType = new TProductSpecificationType();
                tProductSpecificationType.setProductId(tProductCourse.getId());
                tProductSpecificationType.setSpecificationType(Long.valueOf(specificationType));
                tProductSpecificationTypeDao.insert(tProductSpecificationType);
            }
        }
        return tProductCourse.getId();
    }

    @Override
    public TProductCourseNodes editCourseNodes(CourseKnowledgeNode courseKnowledgeNode) {
        TProductCourseNodes tProductCourseNodes = new TProductCourseNodes();
        tProductCourseNodes.setId(courseKnowledgeNode.getId());
        tProductCourseNodes.setCourseId(courseKnowledgeNode.getCourseId());
        tProductCourseNodes.setDuration(courseKnowledgeNode.getDuration());
        tProductCourseNodes.setPlayUrl(courseKnowledgeNode.getPlayUrl());
        tProductCourseNodes.setTeacherId(courseKnowledgeNode.getTeacher().getId());
        tProductCourseNodes.setTeacherHeadUrl(courseKnowledgeNode.getTeacher().getHeadUrl());
        tProductCourseNodes.setTeacherName(courseKnowledgeNode.getTeacher().getName());
        tProductCourseNodes.setName(courseKnowledgeNode.getName().getValue());
        tProductCourseNodes.setSort(courseKnowledgeNode.getSort());
        tProductCourseNodes.setStatus(courseKnowledgeNode.getStatus());
        tProductCourseNodes.setVirtualPurchaseNum(courseKnowledgeNode.getVirtualPurchaseNum());
        tProductCourseNodes.setActualPurchaseNum(courseKnowledgeNode.getActualPurchaseNum());
        tProductCourseNodes.setIsVirtual(courseKnowledgeNode.getIsVirtual());
        tProductCourseNodes.setIsLogistics(courseKnowledgeNode.getIsLogistics());
        if (courseKnowledgeNode.getId()!=null){
            TProductCourseNodes existingCourseNode = productCourseNodesDao.selectById(courseKnowledgeNode.getId());
            if (existingCourseNode != null&& ObjectUtil.defaultIfNull(existingCourseNode.getForceFree(), 0) ==1) {
                tProductCourseNodes.setPrice(BigDecimal.ZERO);
                tProductCourseNodes.setDiscountPrice(BigDecimal.ZERO);
            }else {
                if (courseKnowledgeNode.getPrice() != null) {
                    tProductCourseNodes.setPrice(courseKnowledgeNode.getPrice().getPrice());
                } else {
                    tProductCourseNodes.setPrice(BigDecimal.ZERO);
                }
                if (courseKnowledgeNode.getDiscountPrice() != null) {
                    tProductCourseNodes.setDiscountPrice(courseKnowledgeNode.getDiscountPrice().getPrice());
                } else {
                    tProductCourseNodes.setDiscountPrice(BigDecimal.ZERO);
                }
            }
        }else{
            if (courseKnowledgeNode.getPrice() != null) {
                tProductCourseNodes.setPrice(courseKnowledgeNode.getPrice().getPrice());
            } else {
                tProductCourseNodes.setPrice(BigDecimal.ZERO);
            }
            if (courseKnowledgeNode.getDiscountPrice() != null) {
                tProductCourseNodes.setDiscountPrice(courseKnowledgeNode.getDiscountPrice().getPrice());
            } else {
                tProductCourseNodes.setDiscountPrice(BigDecimal.ZERO);
            }
        }
        tProductCourseNodes.setParentId(courseKnowledgeNode.getParentId());
        tProductCourseNodes.setDescription(courseKnowledgeNode.getDescription());
        tProductCourseNodes.setDetails(courseKnowledgeNode.getDetails());
        tProductCourseNodes.setImageUrl(courseKnowledgeNode.getImageUrl());
        tProductCourseNodes.setScore(courseKnowledgeNode.getScore());
        if (StrUtil.isNotEmpty(courseKnowledgeNode.getFileList())) {
            tProductCourseNodes.setFileList(courseKnowledgeNode.getFileList());
        } else {
            tProductCourseNodes.setFileList("[]");
        }
        tProductCourseNodes.setDeleted(0L);
        tProductCourseNodes.setIsLesson(courseKnowledgeNode.getIsLesson());
        productCourseNodesDao.insertOrUpdate(tProductCourseNodes);
        return tProductCourseNodes;
    }

    @Override
    public CourseKnowledgeNode getCourseNode(Long nodeId) {
        TProductCourseNodes tProductCourseNodes = productCourseNodesDao.selectById(nodeId);
        if (tProductCourseNodes == null || tProductCourseNodes.getDeleted() == null || tProductCourseNodes
                .getDeleted() == 1L) {
            return new CourseKnowledgeNode();
        }
        CourseKnowledgeNode courseKnowledgeNode = new CourseKnowledgeNode();
        courseKnowledgeNode.setId(tProductCourseNodes.getId());
        courseKnowledgeNode.setName(ProductName.of(tProductCourseNodes.getName()));
        courseKnowledgeNode.setPrice(Price.of(tProductCourseNodes.getPrice()));
        courseKnowledgeNode.setDiscountPrice(Price.of(tProductCourseNodes.getDiscountPrice()));
        if (StrUtil.isNotEmpty(tProductCourseNodes.getSpecificationType())) {
            //字符串转数组
            courseKnowledgeNode
                    .setSpecificationType(Arrays
                            .asList(tProductCourseNodes.getSpecificationType().split(",")));
        }
        courseKnowledgeNode.setDetails(tProductCourseNodes.getDetails());
        courseKnowledgeNode.setDescription(tProductCourseNodes.getDescription());
        courseKnowledgeNode.setScore(tProductCourseNodes.getScore());
        courseKnowledgeNode.setImageUrl(tProductCourseNodes.getImageUrl());
        courseKnowledgeNode.setSort(tProductCourseNodes.getSort());
        courseKnowledgeNode.setStatus(tProductCourseNodes.getStatus());
        courseKnowledgeNode.setVirtualPurchaseNum(tProductCourseNodes.getVirtualPurchaseNum());
        courseKnowledgeNode.setActualPurchaseNum(tProductCourseNodes.getActualPurchaseNum());
        courseKnowledgeNode.setIsVirtual(tProductCourseNodes.getIsVirtual());
        courseKnowledgeNode.setIsLogistics(tProductCourseNodes.getIsLogistics());
        courseKnowledgeNode.setCourseId(tProductCourseNodes.getCourseId());
        courseKnowledgeNode.setDuration(tProductCourseNodes.getDuration());
        courseKnowledgeNode.setPlayUrl(tProductCourseNodes.getPlayUrl());
        courseKnowledgeNode.setFileList(tProductCourseNodes.getFileList());
        courseKnowledgeNode.setIsLesson(tProductCourseNodes.getIsLesson());
        courseKnowledgeNode.setParentId(tProductCourseNodes.getParentId());
        Teacher teacher = Teacher.builder()
                .name(tProductCourseNodes.getTeacherName())
                .headUrl(tProductCourseNodes.getTeacherHeadUrl())
                .id(tProductCourseNodes.getTeacherId())
                .build();
        courseKnowledgeNode.setTeacher(teacher);
        return courseKnowledgeNode;
    }

    @Override
    public void deleteCourseNodes(Long nodeId) {
        TProductCourseNodes courseNodes = productCourseNodesDao.selectById(nodeId);
        if (courseNodes != null) {
            courseNodes.setDeleted(1L);
            productCourseNodesDao.updateById(courseNodes);
        }
    }

    @Transactional
    @Override
    public void editCourseNodeConfig(CourseConfig courseConfig) {
        ProductCourseNodesFreeUnlock productCourseNodesFreeUnlock = productCourseNodesFreeUnlockDao.selectOne(new LambdaUpdateWrapper<ProductCourseNodesFreeUnlock>()
                .eq(ProductCourseNodesFreeUnlock::getCourseId, courseConfig.getCourseId()));
        if (productCourseNodesFreeUnlock == null) {
            productCourseNodesFreeUnlock = new ProductCourseNodesFreeUnlock();
            productCourseNodesFreeUnlock.setId(courseConfig.getFreeUnlockConfig().getId());
        }
        productCourseNodesFreeUnlock.setCourseId(courseConfig.getCourseId());
        productCourseNodesFreeUnlock.setCreateUser(courseConfig.getUserId());
        productCourseNodesFreeUnlock.setFreeUnlockSum(courseConfig.getFreeUnlockConfig().getFreeUnlockSum());
        productCourseNodesFreeUnlockDao.insertOrUpdate(productCourseNodesFreeUnlock);
        for (DiscountConfig discountConfig : courseConfig.getDiscountConfig()) {
            ProductCourseBuySumDiscountConfig productCourseBuySumDiscountConfig = new ProductCourseBuySumDiscountConfig();
            productCourseBuySumDiscountConfig.setId(discountConfig.getId());
            productCourseBuySumDiscountConfig.setCourseId(courseConfig.getCourseId());
            productCourseBuySumDiscountConfig.setDiscount(discountConfig.getDiscount());
            productCourseBuySumDiscountConfig.setCourseNodeSum(discountConfig.getCourseNodeSum());
            productCourseBuySumDiscountConfig.setCreateUser(courseConfig.getUserId());
            productCourseBuySumDiscountConfig.setDeleted(discountConfig.getDeleted());
            courseBuySumDiscountConfigDao.insertOrUpdate(productCourseBuySumDiscountConfig);
        }
    }

    @Override
    public CourseConfig getCourseNodeConfig(Long courseId) {
        CourseConfig courseConfig = new CourseConfig();
        //获取课程购买数量优惠配置
        List<ProductCourseBuySumDiscountConfig> courseBuySumDiscountConfigs = courseBuySumDiscountConfigDao
                .selectList(new LambdaQueryWrapper<ProductCourseBuySumDiscountConfig>()
                        .eq(ProductCourseBuySumDiscountConfig::getDeleted, 0L)
                        .eq(ProductCourseBuySumDiscountConfig::getCourseId, courseId));
        if (courseBuySumDiscountConfigs != null && !courseBuySumDiscountConfigs.isEmpty()) {
            List<DiscountConfig> discountConfigList = new ArrayList<>();
            for (ProductCourseBuySumDiscountConfig courseBuySumDiscountConfig : courseBuySumDiscountConfigs) {
                DiscountConfig discountConfig = new DiscountConfig();
                discountConfig.setId(courseBuySumDiscountConfig.getId());
                discountConfig.setCourseNodeSum(courseBuySumDiscountConfig.getCourseNodeSum());
                discountConfig.setDiscount(courseBuySumDiscountConfig.getDiscount());
                discountConfig.setDeleted(courseBuySumDiscountConfig.getDeleted());
                discountConfigList.add(discountConfig);
            }
            courseConfig.setDiscountConfig(discountConfigList);
        } else {
            courseConfig.setDiscountConfig(new ArrayList<>());
        }
        //获取课程免费解锁配置
        ProductCourseNodesFreeUnlock productCourseNodesFreeUnlock = productCourseNodesFreeUnlockDao
                .selectOne(new LambdaQueryWrapper<ProductCourseNodesFreeUnlock>()
                        .eq(ProductCourseNodesFreeUnlock::getCourseId, courseId));
        if (productCourseNodesFreeUnlock != null) {
            FreeUnlockConfig config = new FreeUnlockConfig();
            config.setId(productCourseNodesFreeUnlock.getId());
            config.setFreeUnlockSum(productCourseNodesFreeUnlock.getFreeUnlockSum());
            courseConfig.setFreeUnlockConfig(config);
        }
        return courseConfig;
    }

    @Override
    public void updateCoursePrice(Long id, BigDecimal price, BigDecimal discountPrice) {
        TProductCourse tProductCourse = new TProductCourse();
        tProductCourse.setId(id);
        tProductCourse.setPrice(price);
        tProductCourse.setDiscountPrice(discountPrice);
        productCourseDao.updateById(tProductCourse);
    }

    @Override
    public List<MemberCourseOrder> getMemberCourse(Long userId, String courseName, String sort) {
        return productCourseDao.getMemberCourse(userId, courseName, sort);
    }

    @Override
    public boolean isK12(Long courseId) {
        TProductCourse tProductCourse =productCourseDao.selectById(courseId);
        return tProductCourse!=null && ObjectUtil.defaultIfNull(tProductCourse.getCourseType(),0)==1;
    }

    @Override
    public TProductCourse ofCourse(Long courseId) {
        return productCourseDao.selectById(courseId);
    }

    @Override
    public int updateProductCourse(TProductCourse productCourse) {
        return productCourseDao.updateById(productCourse);
    }

    @Override
    public List<Long> selectCourseIdsByPrefixSpecTag(String versionPrefix, String specTag) {
        if (StrUtil.isNotBlank(versionPrefix)) {
            return productCourseDao.selectCourseIdsByPrefixSpecTag(versionPrefix, specTag);
        }
        return List.of();
    }

    @Override
    public void updateCourseStatusById(Long courseId, Integer status) {
        productCourseDao.update(Wrappers.lambdaUpdate(TProductCourse.class).eq(BaseIdDO::getId, courseId).set(BaseProduct::getStatus, status));
    }
}
